package com.boarsoft.boar.config.lock.listener.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import com.boarsoft.boar.config.lock.biz.LockInfoBiz;
import com.boarsoft.rpc.core.RpcContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.dao.DataIntegrityViolationException;

import com.boarsoft.boar.config.lock.LockInfo;
import com.boarsoft.boar.config.lock.LockListener;
import com.boarsoft.boar.config.lock.biz.LockListenerBiz;
import com.boarsoft.boar.config.lock.listener.CommonLockListener;
import com.boarsoft.boar.config.service.LockNoticeServie;

public class CommonLockListenerImpl implements CommonLockListener {
    private static final Logger log = LoggerFactory.getLogger(CommonLockListenerImpl.class);
    private final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    LockNoticeServie lockNoticeServie;
    @Autowired
    private ApplicationContext appCtx;
    @Resource
    LockListenerBiz lockListenerBiz;

    @Resource
    LockInfoBiz lockInfoBiz;

    @Override
    public void onLocked(String url, String appId, String type, String address) {
        try {
            LockListener lockListener = new LockListener();
            lockListener.setAddress(address);
            lockListener.setType(type);
            lockListener.setUrl(url);
            lockListener.setAppId(appId);
            lockListener.setCreateTime(formatter.format(new Date()));
            lockListenerBiz.save(lockListener);
        } catch (DataIntegrityViolationException e) {
            log.debug("已在抢锁列表中");
        }
    }

    /**
     * 解锁时的监听方法
     * @param lockInfo 锁监息
     */
    @Override
    public void onUnLock(LockInfo lockInfo,String[] mutexs) {
        List<LockListener> lockListeners = this.getLockListener(lockInfo, mutexs);
        lockListeners.forEach(lockListener -> {
            //通知已登记的资源抢锁
            this.notice(lockListener);
            lockListenerBiz.delete(lockListener);
        });
    }

    @Override
    public void onNotice(LockInfo lockInfo, String type) {
        List<LockInfo> lockInfos = lockInfoBiz.find(lockInfo.getAppId(),lockInfo.getUrl(),null,type);
        //通知已登记的资源抢锁
        lockInfos.forEach(lockInfo1 -> {
            sendUpdate(lockInfo1);
        });
    }

    /**
     * 通知更新数据
     * @param lockInfo 锁列表
     */
    private void sendUpdate(LockInfo lockInfo) {
        try {
            lockNoticeServie = appCtx.getBean("lockNoticeServie", LockNoticeServie.class);
            //RpcContext.specify2(lockInfo.getAddress());
            lockNoticeServie.sendUpdate(lockInfo);
        }catch(Exception e){
            log.error("发送通知异常！",e);
        }
    }
    /**
     * 通知抢锁队列中的等待抢锁的地址
     * @param lockListener 锁等待列表
     */
    private void notice(LockListener lockListener) {
        try {
            lockNoticeServie = appCtx.getBean("lockNoticeServie", LockNoticeServie.class);
            //RpcContext.specify2(lockListener.getAddress());
            lockNoticeServie.sendNotice(lockListener);
        }catch(Exception e){
            log.debug("发送通知异常！");
        }
    }

    /**
     * 获取当前锁互斥的等待列表
     * @param lockInfo 加锁监息
     * @param mutexs    互斥列表
     * @return  监听锁列表
     */
    private List<LockListener> getLockListener(LockInfo lockInfo,String[] mutexs) {
        List<LockListener> lockListeners = new ArrayList<>();
        for (String mutex : mutexs) {
            lockListeners.addAll(lockListenerBiz.find(lockInfo.getUrl(),lockInfo.getAppId()
                    ,mutex));
        }
        return lockListeners;
    }

}